/*
 * 注意，编译本程序的命令：gcc msg.c -o msg -lpthread -std=gnu99
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include "list.h"
	
#define PAUSE 1000000

void *run(void *); /* 消息处理线程 */
void add_msg(int);
struct msg_buff *getnextmsg(struct list_head *);
void handle_msg(struct msg_buff *);

struct msg_buff {
   int id; 
   struct list_head list;
};

/* 线程互斥量 */
pthread_mutex_t mqlock = PTHREAD_MUTEX_INITIALIZER;        
/* 条件变量 */
pthread_cond_t mqlock_ready = PTHREAD_COND_INITIALIZER; 

pthread_t tid; /* 消息处理线程id */
LIST_HEAD(msg_queue); /* 消息队列 */

int main()
{
    int err = 0;
 
    err = pthread_create(&tid, NULL, run, NULL);/* 创建并启动消息处理线程 */
    
    for(int i = 0; i < 10; i++){
    	add_msg(i);/* 向消息队列添加消息 */
    	
    	usleep(PAUSE);/* 等待1秒 */
    }    
	
    return 0;
}

void add_msg(int i)
{
   struct msg_buff *tmp = malloc(sizeof(struct msg_buff));
   tmp->id = i+1;
   list_add_tail(&tmp->list, &msg_queue);
}

void *run(void *arg)
{
    struct msg_buff *msg;

    for (int i = 10; i > 0; i--) {
      // 通过getnextmsg函数从队列中取下一消息
      getnextmsg(&msg -> list);
      handle_msg(msg); /* 处理消息 */         
   }
}

struct msg_buff *getnextmsg(struct list_head *q)
{
	struct msg_buff *msg;
  // 完成从队列中取下一消息代码
  msg = list_entry(q, struct msg_buff, list);
  struct list_head *p = &msg -> list;
  msg = list_entry(p, struct msg_buff, list);
  return msg;
}

void handle_msg(struct msg_buff *m)
{
	printf("m->id=%d\n", m->id); /* 处理此分组 */
}
